/**
 * 小程序AI聊天接口对接工具类
 * 基于异步接口+轮询的方式实现稳定的聊天功能
 * 支持流式接口降级到异步接口的双重保障
 * 
 * @author AI客服系统
 * @version 2.0.0
 */

class ChatAPI {
  constructor(config = {}) {
    // 配置参数
    this.baseUrl = config.baseUrl || 'http://localhost:8080/api';
    this.pollingInterval = config.pollingInterval || 1000; // 轮询间隔(ms)
    this.maxPollingTime = config.maxPollingTime || 30000; // 最大轮询时间(ms)
    this.retryTimes = config.retryTimes || 3; // 重试次数
    this.enableStreamFirst = config.enableStreamFirst !== false; // 是否优先尝试流式接口
    
    // 回调函数
    this.onMessage = config.onMessage || null;
    this.onError = config.onError || null;
    this.onComplete = config.onComplete || null;
    this.onConnectionChange = config.onConnectionChange || null;
    
    // 内部状态
    this.currentTaskId = null;
    this.isPolling = false;
    this.sessionId = null;
    this.isDestroyed = false;
  }

  /**
   * 发送聊天消息（主要接口）
   * @param {string} message 消息内容
   * @param {Object} context 上下文信息（可选）
   * @returns {Promise<Object>} 聊天结果
   */
  async sendMessage(message, context = {}) {
    if (this.isDestroyed) {
      throw new Error('ChatAPI已销毁');
    }

    try {
      // 参数验证
      this._validateMessage(message);

      console.log('[ChatAPI] 开始发送消息:', message.substring(0, 50) + '...');

      // 触发连接状态变化
      this._triggerConnectionChange('connecting');

      let result;
      
      // 优先尝试流式接口
      if (this.enableStreamFirst) {
        try {
          result = await this._tryStreamChat(message, context);
          console.log('[ChatAPI] 流式接口成功');
        } catch (streamError) {
          console.warn('[ChatAPI] 流式接口失败，降级到异步接口:', streamError.message);
          result = await this._useAsyncChat(message, context);
        }
      } else {
        // 直接使用异步接口
        result = await this._useAsyncChat(message, context);
      }
      
      // 保存会话ID
      if (result.sessionId) {
        this.sessionId = result.sessionId;
      }
      
      // 触发完成回调
      this._triggerComplete({
        ...result,
        context: context
      });

      return result;

    } catch (error) {
      console.error('[ChatAPI] 发送消息失败:', error);
      
      // 触发错误回调
      this._triggerError(error);
      
      throw error;
    } finally {
      this.currentTaskId = null;
      this.isPolling = false;
    }
  }

  /**
   * 取消当前任务
   */
  async cancelCurrentTask() {
    if (this.currentTaskId && this.isPolling) {
      try {
        await this._cancelTask(this.currentTaskId);
        this.isPolling = false;
        this._triggerConnectionChange('idle');
        console.log('[ChatAPI] 任务已取消:', this.currentTaskId);
      } catch (error) {
        console.error('[ChatAPI] 取消任务失败:', error);
      }
    }
  }

  /**
   * 销毁ChatAPI实例
   */
  destroy() {
    this.isDestroyed = true;
    this.isPolling = false;
    this.currentTaskId = null;
    this.sessionId = null;
    
    // 清空回调函数
    this.onMessage = null;
    this.onError = null;
    this.onComplete = null;
    this.onConnectionChange = null;
    
    console.log('[ChatAPI] 实例已销毁');
  }

  /**
   * 获取系统状态
   */
  async getSystemStatus() {
    try {
      const response = await this._request({
        url: `${this.baseUrl}/api/chat/async/system/status`,
        method: 'GET'
      });
      return response.data;
    } catch (error) {
      console.error('获取系统状态失败:', error);
      return { status: 'unknown', error: error.message };
    }
  }

  // ==================== 私有方法 ====================

  /**
   * 参数验证
   */
  _validateMessage(message) {
    if (!message || !message.trim()) {
      throw new Error('消息内容不能为空');
    }

    if (message.length > 2000) {
      throw new Error('消息内容过长，请控制在2000字符以内');
    }
  }

  /**
   * 触发消息回调
   */
  _triggerMessage(data) {
    if (this.onMessage && !this.isDestroyed) {
      this.onMessage(data);
    }
  }

  /**
   * 触发错误回调
   */
  _triggerError(error) {
    if (this.onError && !this.isDestroyed) {
      this.onError(error);
    }
  }

  /**
   * 触发完成回调
   */
  _triggerComplete(data) {
    if (this.onComplete && !this.isDestroyed) {
      this.onComplete(data);
    }
    this._triggerConnectionChange('connected');
  }

  /**
   * 触发连接状态变化回调
   */
  _triggerConnectionChange(status) {
    if (this.onConnectionChange && !this.isDestroyed) {
      this.onConnectionChange(status);
    }
  }

  /**
   * 尝试流式接口
   */
  async _tryStreamChat(message, context) {
    const response = await this._request({
      url: `${this.baseUrl}/api/chat/stream`,
      method: 'POST',
      header: {
        'Content-Type': 'application/json',
        'Accept': 'text/event-stream',
        'Cache-Control': 'no-cache'
      },
      data: {
        message: message,
        sessionId: this.sessionId,
        userId: uni.getStorageSync('userId') || 'anonymous'
      },
      responseType: 'text',
      timeout: 10000 // 流式接口10秒超时
    });

    // 检查HTTP状态码
    if (response.statusCode !== 200) {
      throw new Error(`流式接口HTTP错误: ${response.statusCode}`);
    }

    // 处理流式响应
    return await this._processStreamResponse(response.data, context);
  }

  /**
   * 处理流式响应数据
   */
  async _processStreamResponse(responseData, context) {
    if (!responseData || typeof responseData !== 'string') {
      throw new Error('流式响应数据格式错误');
    }

    const lines = responseData.split('\n');
    let fullContent = '';
    let hasValidData = false;
    let sessionId = null;

    for (const line of lines) {
      const trimmedLine = line.trim();
      if (trimmedLine.startsWith('data: ')) {
        try {
          const jsonStr = trimmedLine.substring(6).trim();
          if (jsonStr === '[DONE]') {
            // 流结束标记
            break;
          }

          const data = JSON.parse(jsonStr);
          hasValidData = true;

          switch (data.type) {
            case 'start':
              // 开始接收内容
              break;

            case 'content':
              fullContent += data.content || '';
              // 触发消息回调
              this._triggerMessage({
                content: fullContent,
                context: context
              });
              break;

            case 'end':
              sessionId = data.sessionId;
              return {
                reply: fullContent,
                sessionId: sessionId,
                completeTime: new Date().toISOString(),
                source: 'stream',
                responseTime: data.responseTime,
                fromCache: data.fromCache
              };

            case 'error':
              throw new Error(data.message || '流式处理出错');
          }
        } catch (parseError) {
          console.warn('[ChatAPI] 解析SSE数据失败:', trimmedLine, parseError);
        }
      }
    }

    if (!hasValidData) {
      throw new Error('未找到有效的流式数据');
    }

    // 如果没有收到end事件但有内容，返回现有内容
    if (fullContent) {
      return {
        reply: fullContent,
        sessionId: sessionId,
        completeTime: new Date().toISOString(),
        source: 'stream'
      };
    }

    throw new Error('流式接口未返回有效内容');
  }

  /**
   * 使用异步接口
   */
  async _useAsyncChat(message, context) {
    // 1. 提交异步任务
    const taskResponse = await this._submitAsyncTask(message);
    this.currentTaskId = taskResponse.taskId;

    console.log('[ChatAPI] 异步任务已提交:', this.currentTaskId);

    // 2. 轮询获取结果
    const result = await this._pollTaskResult(this.currentTaskId, context);
    
    return {
      ...result,
      source: 'async'
    };
  }

  /**
   * 提交异步任务
   */
  async _submitAsyncTask(message) {
    const requestData = { 
      message
    };
    
    if (this.sessionId) {
      requestData.sessionId = this.sessionId;
    }

    const response = await this._request({
      url: `${this.baseUrl}/api/chat/async`,
      method: 'POST',
      data: requestData
    });

    if (!response.data || !response.data.taskId) {
      throw new Error(response.data?.message || '提交异步任务失败');
    }

    return response.data;
  }

  /**
   * 轮询任务结果
   */
  async _pollTaskResult(taskId, context) {
    this.isPolling = true;
    const startTime = Date.now();
    let lastContent = '';

    while (this.isPolling && (Date.now() - startTime) < this.maxPollingTime) {
      try {
        // 查询任务状态
        const statusResponse = await this._request({
          url: `${this.baseUrl}/api/chat/async/${taskId}/status`,
          method: 'GET'
        });

        const status = statusResponse.data;
        
        // 如果有部分内容更新，触发消息回调
        if (status.partialContent && status.partialContent !== lastContent) {
          this._triggerMessage({
            content: status.partialContent,
            context: context
          });
          lastContent = status.partialContent;
        }

        // 检查是否完成
        if (status.completed) {
          if (status.hasResult) {
            // 获取结果
            return await this._getTaskResult(taskId);
          } else {
            throw new Error(status.message || '任务处理失败');
          }
        }

        // 等待后继续轮询
        await this._sleep(this.pollingInterval);

      } catch (error) {
        // 网络错误重试
        if (this._isNetworkError(error)) {
          console.warn('[ChatAPI] 网络错误，等待重试...');
          await this._sleep(this.pollingInterval * 2);
          continue;
        }
        throw error;
      }
    }

    throw new Error('任务处理超时，请重试');
  }

  /**
   * 获取任务结果
   */
  async _getTaskResult(taskId) {
    const response = await this._request({
      url: `${this.baseUrl}/api/chat/async/${taskId}/result`,
      method: 'GET'
    });

    const result = response.data;
    if (result.status !== 'success') {
      throw new Error(result.errorMessage || '获取结果失败');
    }

    return {
      reply: result.reply,
      sessionId: result.sessionId,
      completeTime: result.completeTime,
      taskId: taskId,
      responseTime: result.responseTime,
      fromCache: result.fromCache
    };
  }

  /**
   * 取消任务
   */
  async _cancelTask(taskId) {
    try {
      await this._request({
        url: `${this.baseUrl}/api/chat/async/${taskId}`,
        method: 'DELETE'
      });
    } catch (error) {
      console.warn('取消任务失败:', error);
    }
  }

  /**
   * 统一请求方法
   */
  async _request(options, retryCount = 0) {
    try {
      const response = await new Promise((resolve, reject) => {
        uni.request({
          ...options,
          header: {
            'Content-Type': 'application/json',
            ...options.header
          },
          success: resolve,
          fail: reject
        });
      });

      // 检查HTTP状态码
      if (response.statusCode >= 400) {
        throw new Error(`HTTP ${response.statusCode}: ${response.data?.message || '请求失败'}`);
      }

      return response;

    } catch (error) {
      // 重试逻辑
      if (retryCount < this.retryTimes && this._isNetworkError(error)) {
        console.warn(`[ChatAPI] 请求失败，第${retryCount + 1}次重试...`);
        await this._sleep(1000 * (retryCount + 1)); // 递增延时
        return this._request(options, retryCount + 1);
      }
      throw error;
    }
  }

  /**
   * 判断是否为网络错误
   */
  _isNetworkError(error) {
    return error.errMsg && (
      error.errMsg.includes('timeout') ||
      error.errMsg.includes('fail') ||
      error.errMsg.includes('network') ||
      error.errMsg.includes('request:fail')
    );
  }

  /**
   * 延时函数
   */
  _sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

// 导出
export default ChatAPI;

// 兼容CommonJS
if (typeof module !== 'undefined' && module.exports) {
  module.exports = ChatAPI;
}